<template>
  <div>
    <base-modal
      class="material-apply-dialog-container"
      :show.sync="visible"
      :title="$t('task.detail.components.addApply')"
      width="900px"
      append-to-body
    >
      <!-- start 出库方式 -->
      <div class="material-apply-method-panel">
        <span class="label-right">{{$t('task.detail.components.outStockMethod')}}</span> 
        <el-radio-group v-model="params.targetSite" @change="changeTargetSite">
          <el-radio label="person" v-if="!isTaskCloudWarehousePerson && allowApplyPerson">{{$t('task.detail.components.applyToPersonal')}}</el-radio>
          <el-radio v-if="allowApplyMaterialOut" label="task">{{$t('task.detail.components.applyToTask')}}</el-radio>
        </el-radio-group>
      </div>

      <form-builder v-if="openPersonalRepertory" :is-validate-by-parent="false" :fields="warehouseFields" ref="form" :value="form" @update="update" class="warehouse-form">

        <template slot="warehouse" slot-scope="{ field }">
          <form-item :label="$t('common.form.preview.materialReturn.label1')" class="warehouse-form-select">
            <form-select
              :placeholder="field.placeholder" 
              :field="field" 
              :source="warehouseList" 
              v-model="form.personWarehouseId" 
              clearable/>
          </form-item>
        </template>

        <template slot="warehousePosition" slot-scope="{ field }">
          <form-item :label="$t('common.form.preview.materialReturn.label2')" class="warehouse-form-select">
            <form-select
              :placeholder="field.placeholder" 
              :field="field" 
              :source="warehousePositionList" 
              v-model="form.personPositionId" 
              @update="updateWarehousePositionId" 
              clearable/>
          </form-item>
        </template>

      </form-builder>
      <!-- end 出库方式 -->

      <material-table
        ref="materialTable"
        :data="data"
        :columns="columns"
        :card="card"
        :get-warehouse-aggregate="getWarehouseAggregate"
        :can-select-material="!isOnlyMaterialOut"
        :is-only-material-out="isOnlyMaterialOut"
        :allow-select-warehouse="allowSelectWarehouse"
        :warranty-status="warrantyStatus"
        :warranty-status-data="warrantyStatusData"
        :allow-warranty-change="allowWarrantyChange"
        v-if="visible"
        :open-dialog-mode="true"
        :cardConfig="cardConfig"
      />

      <div v-if="!isOnlyMaterialOut" class="btn-group">
        <el-button type="primary" icon="el-icon-plus" @click="addPart">{{$t('task.edit.chooseMaterial')}}</el-button>
      </div>

      <div slot="footer" class="dialog-footer">
        <el-button @click="visible = false">{{$t('common.base.cancel')}}</el-button>
        <el-button type="primary" @click="next">{{$t('common.base.nextStep')}}</el-button>
      </div>
    </base-modal>
    <material-receiving-information-dialog
      ref="receivingInformationDialog" 
      :task="task"
      :pending="pending"
      @pre="pre"
      @submit="submit"/>

    <!-- 服务BOM清单 -->
    <material-service-bom-dialog 
      ref="materialServiceRef" 
      :columns="columns" 
      :dataList="data"
      @handleSubmit="handleSubmit" 
      :getWarehouseAggregate="getWarehouseAggregate"
      :warranty-status="warrantyStatus"
      :warranty-status-data="warrantyStatusData"
      :productTemplate="productTemplate">
    </material-service-bom-dialog>
  </div>
</template>

<script>
/* api */
import * as TaskApi from '@src/api/TaskApi';
import * as WareHouseApi from '@src/api/WareHouseApi';
/* components */
import MaterialReceivingInformationDialog from './MaterialReceivingInformationDialog.vue';
import MaterialServiceBomDialog from '@src/modules/task/editAllot/components/PartSeviceList/components/MaterialServiceBomDialog.vue';
// import MaterialTable from './MaterialTable.vue';
import MaterialTable from '@src/modules/task/editAllot/components/PartSeviceList/components/MaterialTable.vue';

/* enum */
import { TaskEventNameMappingEnum } from '@model/enum/EventNameMappingEnum.ts';
/* model */
import { PART_SERVICE_LIST_MAX_LENGTH } from '@src/model/const/Number';
import { PART_SERVICE_LIST_MAX_LENGTH_MESSAGE } from '@src/model/const/Alert';
/* util */
import _ from 'lodash';
import { getRootWindow } from '@src/util/dom'

export default {
  name: 'material-apply-dialog',
  props: {
    fields: {
      type: Array,
      default: () => ([])
    },
    card: {
      type: Object,
      default: () => ({})
    },
    task: {
      type: Object,
      default: () => ({})
    },
    value: {
      type: Array,
      default: () => ([])
    },
    // 是否是工单负责人
    isExecutor: {
      type: Boolean,
      default: false
    },
    // 是否是工单协同人
    isSynergies: {
      type: Boolean,
      default: false
    },
    // 允许物料申领时选择仓库
    allowSelectWarehouse: {
      type: Boolean,
      default: false
    },
    allowWarrantyChange: {
      type: Boolean,
      default: false
    },
    // 质保状态
    warrantyStatus: {
      type: Number
    },
    warrantyStatusData: {
      type: Array,
      default: () => ([])
    },
    tags: {
      type: Object,
      default: () => ({})
    },
    productTemplate: {
      type: Array,
      default: () => ([])
    }
  },
  data() {
    return {
      pending: false,
      visible: false,
      isOnlyMaterialOut: true,
      data: [],
      params: {},
      form: {
        personWarehouseId: '',
        personPositionId: ''
      },
      warehouseList: [],
      warehousePositionList: [],
      // 仓库仓位列表
      warehouseData: [],
      warehousePositionData: [],
      // 默认仓库仓位
      warehouse: {},
      warehousePosition: {},
      inventoryParams: {},
      availableStock: [], // 可用库存
    }
  },
  computed: {
    customerAddress() {
      return this.task?.customer?.customerAddress || {}
    },
    // 是否开启个人库灰度
    isTaskCloudWarehousePerson() {
      const RootWindow = getRootWindow(window)
      return RootWindow.grayAuth?.taskCloudWarehousePerson || false
    },
    columns() {
      let fields = _.cloneDeep(this.fields)

      fields = [
        ...fields,
        {
          displayName: this.$t('common.form.preview.sparepart.colum9'),
          fieldName: 'warehouse',
          width: '150px',
          tooltip: false,
          isFixed: 'right'
        },
        {
          displayName: this.$t('common.form.preview.sparepart.colum12'),
          fieldName: 'warehousePosition',
          width: '150px',
          tooltip: false,
          isFixed: 'right'
        },
        {
          displayName: this.$t('common.form.preview.sparepart.colum13'),
          fieldName: 'availableNum',
          width: '80px',
          isFixed: 'right'
        },
        {
          displayName: this.$t('common.base.operation'),
          fieldName: 'action',
          isFixed: 'right'
        }
      ]

      fields.forEach(field => {
        if (field.fieldName == 'name') {
          field.width = '160px';
        } else if (field.fieldName == 'preNum') {
          field.width = '140px';
          // 修改预计用量为申领用量
          field.displayName = this.$t('task.detail.components.applyNumber')
        } else if (field.fieldName == 'warrantyStatus') {
          field.width = '150px';
        } else if (field.fieldName == 'snManage') {
          field.width = '110px';
        }
        field.tooltip = field.tooltip ?? true
      })
      return fields;
    },
    /** 物料清单附加组件配置 */
    cardConfig() {
      return JSON.parse(this.card.config || '{}');
    },
    // 申领出库数量大于可用库存数量
    isAllowGtInventory() {
      return this.cardConfig?.allowGtInventory || false
    },
    /** 
    * @description 允许出库至工单
    * 1. 开启了「 允许出库至工单 」
    * 2. 且 登录账号是否是被允许使用的角色（工单负责人或协同人）
    */
    allowApplyMaterialOut() {
      let { isOutRep2Task, roleList = [] } = this.cardConfig;

      // 判断登录账号是否是被允许使用的角色
      let hasAuthRole = (this.isExecutor && roleList.includes('taskPrincipalPerson')) || (this.isSynergies && roleList.includes('taskSynergyPerson'));
      return isOutRep2Task && hasAuthRole;
    },
    // 是否允许出库个人备件库
    allowApplyPerson() {
      return this.cardConfig?.isOutRep2Person || false
    },
    /** 是否显示个人仓库位 */
    openPersonalRepertory() {
      // 统一隐藏掉个人库选择
      // return this.params.targetSite === 'person'
      return false
    },
    warehouseFields() {
      return [
        {
          formType: 'select',
          fieldName: 'warehouse',
          displayName: this.$t('common.form.preview.materialReturn.label1'),
          placeholder: this.$t('common.form.placeHolder.materialReturn.pla3'),
          isNull: 0,
          disabled: true,
          setting: {}
        },
        {
          formType: 'select',
          fieldName: 'warehousePosition',
          displayName: this.$t('common.form.preview.materialReturn.label2'),
          placeholder: this.$t('common.form.placeHolder.materialReturn.pla2'),
          isNull: 0,
          setting: {}
        }
      ]
    },
    /**
    * @description 仓库仓位数据集合
    */
    getWarehouseAggregate() {
      let { warehouse, warehouseData, warehousePosition, warehousePositionData } = this
      return {
        warehouse,
        warehouseData,
        warehousePosition,
        warehousePositionData
      }
    }
  },
  watch: {
    getWarehouseAggregate(value) {
      this.buildData()
    }
  },
  methods: {
    buildParams() {
      let { id, taskNo } = this.task;

      return {
        taskNo,
        taskId: id,
        materials: [],
        taskCardId: this.card.cardId,
        targetSite: this.isTaskCloudWarehousePerson ? 'task' : 'person',
        personWarehouseId: '',
        personPositionId: ''
      }
    },
    /**
    * @description 获取个人仓库位置
    */
    getPersonalWarehouseData() {
      WareHouseApi.getPersonalInventoryWarehouse()
        .then((result) => {
          
          if (result?.success) {
            let warehouse = result?.data.warehouse || {}
            let warehousePositionList = result?.data.warehousePositionList || []
            this.warehouseList.push({
              text: warehouse.name,
              value: warehouse.id
            })
            this.form.personWarehouseId = this.warehouseList[0]?.value
            this.warehousePositionList = warehousePositionList.map(item => {
              return {
                text: item.name,
                value: item.id
              }
            })
            this.form.personPositionId = this.warehousePositionList[0]?.value
          }
          
        }).catch(error => {
          console.error(error);
        })
    },
    updateWarehousePositionId({ newValue }) {
      this.form.personPositionId = newValue
    },
    update({ field, newValue, oldValue }) {
      let { fieldName, displayName } = field
      if (this.$appConfig.debug) {
        console.info(`[FormBuilder] => ${displayName}(${fieldName}) : ${JSON.stringify(newValue)}`);
      }
      this.$set(this.form, fieldName, newValue)
    },
    /**
    * @description 打开弹窗
    */
    open(isOnlyMaterialOut = true, data = [], params = {}) {
      this.isOnlyMaterialOut = isOnlyMaterialOut
      this.data = data
      this.buildData()
      this.pending = false
      this.visible = true

      this.params = this.buildParams()

      if(!isOnlyMaterialOut) {
        // this.$nextTick(() => {
        //   // 默认添加一行数据
        //   this.addPart()
        // })
      }
      this.changeTargetSite(this.params.targetSite)
      
      // 获取个人仓库位置
      this.getPersonalWarehouseData()
    },
    buildData() {
      let { warehouse, warehouseData, warehousePosition, warehousePositionData } = this.getWarehouseAggregate
      this.data.forEach(item => {
        item.warehouse = warehouse,
        item.warehouseId = warehouse.value,
        item.warehouseData = warehouseData,
        item.warehousePosition = warehousePosition,
        item.positionId = warehousePosition.value,
        item.warehousePositionData = warehousePositionData
      })
    },
    /**
    * @description 添加备件
    */
    addPart() {
      this.$refs.materialServiceRef.openMaterialList()
    },
    /**
    * @description 提交
    * @param {Object} formParams 新增并申领物料参数
    */
    submit(formParams) {
      this.params = {
        ...this.params,
        ...formParams,
        ...this.form
      }
      this.pending = true
      let api = this.isOnlyMaterialOut ? 'addInventoryApply' : 'addInventoryAndApply';
      TaskApi[api](this.params)
        .then(res => {
          if (res.success) {
            this.$platform.notification({
              type: 'success',
              title: this.$t('common.base.submitSuccess')
            })
            
            this.$parent.getInventoryByCardId();
            this.pending = false;
            this.$refs.receivingInformationDialog.close()
            this.$eventBus.$emit(TaskEventNameMappingEnum.UpdateRecord);
          } else {
            this.$platform.alert(res.message);
            this.pending = false;
          }
        }).catch(err => {
          this.pending = false;
        })
    },
    async next() {
      // 过滤掉空数据
      let selectedData = this.data.filter(item => item.id);
      if (selectedData.length == 0) return this.$platform.alert(this.$t('task.tip.applyMaterialTip1'));

      // 个人库仓位必填校验
      if (this.params.targetSite === 'person' && !this.form.personPositionId) return this.$platform.alert(this.$t('task.tip.applyMaterialTip2'));

      // 物料必须填写仓库仓位
      let isPositionData = this.data.filter(item => !item.positionId)
      if (isPositionData.length) return this.$platform.alert(this.$t('task.tip.applyMaterialTip3', {msg:isPositionData[0].name}));

      // 校验申请数量是否超出可用库存
      // if(this.allowSelectWarehouse) {
      //   let isNumErrorArr = this.data.filter(item => item.id && (Number(item.allowNum) > Number(item.availableNum)));
      //   if (isNumErrorArr.length) return this.$platform.alert(`「${isNumErrorArr[0].name}」的申领用量不能超过可用库存`);
      // }

      // 申领总数不能为零
      let isPreNum = this.data.filter(item => item.id && (Number(item.preNum) === 0))
      if(isPreNum.length) return this.$platform.alert(this.$t('task.tip.applyMaterialTip4', {msg:isPreNum[0].name}));
      // 申领总数不能超出可申领数量
      let isPreNumErrorArr = this.data.filter(item => item.id && (Number(item.preNum) > Number(item.allowNum)));
      if(isPreNumErrorArr.length && !this.isAllowGtInventory) return this.$platform.alert(this.$t('task.tip.applyMaterialTip5', {msg:isPreNumErrorArr[0].name}));

      // 是否超过最大限制
      let isOverLimit = this.value.length + selectedData.length > PART_SERVICE_LIST_MAX_LENGTH;
      if (isOverLimit) return this.$platform.alert(PART_SERVICE_LIST_MAX_LENGTH_MESSAGE);

      // 校验质保状态
      let warrantyStatus = this.data.filter(item => item.warrantyStatus == undefined)
      let warrantyStatusColumns = this.columns.filter(item => item.fieldName == 'warrantyStatus')
      if (this.allowWarrantyChange && warrantyStatusColumns.length && warrantyStatus.length && !this.isOnlyMaterialOut) return this.$platform.alert(this.$t('task.tip.applyMaterialTip6'));

      // 校验质保状态
      // TODO 国际化待办
      let warrantyConfirmationData = this.data.filter(item => item.warrantyConfirmation === '待办理')
      if (warrantyConfirmationData.length) return this.$platform.alert(this.$t('task.tip.applyMaterialTip7'));

      this.params.materials = [];
      selectedData.forEach(item => {
        this.params.materials.push({
          id: this.isOnlyMaterialOut ? item.relatedId : item.id,
          inventoryId: this.isOnlyMaterialOut ? item.id : null,
          num: Number(item.preNum),
          name: item.name,
          warehouseId: item.warehouse?.value || item.warehouseId,
          positionId: item.warehousePosition?.value || item.positionId,
          warrantyStatus: item.warrantyStatus,
          warrantyConfirmation: item.warrantyConfirmation,
          paasRelationId: item.paasRelationId
        })
      })

      // 仓库仓位必填校验
      let isEmptyRepertoryArr = this.params.materials.filter(item => !item.warehouseId || !item.positionId);
      if (isEmptyRepertoryArr.length) return this.$platform.alert(this.$t('task.tip.applyMaterialTip8', {msg:isEmptyRepertoryArr[0].name}));
      
      this.$refs.receivingInformationDialog.open()
      this.visible = false
    },
    pre() {
      this.$refs.receivingInformationDialog.close()
      this.visible = true
      this.$nextTick(() => {
        this.data = this.data.map(item => {
          return {
            label: item.name,
            value: item.id,
            ...item,
          }
        })
      })
    },
    /** 
     * @description 切换出库方式
    */
    changeTargetSite(value) {
      let outWarehouseType = value === 'person' ? 'APPLY_OUT' : 'TASK_OUT'
      this.getDefaultWarehouse(outWarehouseType)
    },
    /** 
     * @description 获取默认仓库列表
    */
    getDefaultWarehouse(outWarehouseType) {
      const materialIds = (this.data || []).map(item => {
        return item.relatedId
      })

      const params = {
        taskId: this.task?.id,
        materialIds
      }

      WareHouseApi.getDefaultWarehouseBinInventory(params)
        .then(ret => {
          if (ret?.success) {
            const { warehouseName, warehouseId, warehousePositionName, warehousePositionId, materialInfoList } = ret.result || {}

            // if (!warehouseId) return

            this.warehouse = {
              label: warehouseName,
              value: warehouseId,
              typeName: 'default'
            }
            this.warehousePosition = {
              label: warehousePositionName,
              value: warehousePositionId,
              typeName: 'default'
            }

            this.availableStock = materialInfoList || [];

            if(this.warehouse.value) {
              this.getDefaultWarehousePosition(this.warehouse.value)
            }
            
            this.getWarehouseSearch()

            let materialIds = this.data.map(item => item.relatedId)
            this.inventoryParams.materialIds = materialIds
            this.inventoryParams.warehouseId = this.warehouse?.value || ''
            this.inventoryParams.positionId = this.warehousePosition?.value || ''
            

            this.$nextTick(() => {
              this.$refs.materialTable.getInventoryList(this.inventoryParams)
            })
          }
        }).catch(error => {
          console.error(error);
        })
    },
    /** 
     * @description 获取仓库列表 
    */
    getWarehouseSearch() {
      WareHouseApi.getTaskWarehouseSearch({ taskId: this.task?.id })
        .then((ret) => {
          if (ret?.success) {
            let data = ret?.result || []
            let warehouseData = []
            data.forEach(item => {
              let index = this.warehouseData.findIndex(warehouse => warehouse.value === item.id)
              if(index < 0) {
                warehouseData.push({
                  label: item.name,
                  value: item.id
                }) 
              }
            })
            this.warehouseData = this.warehouseData.concat(warehouseData)
            
            // 获取新的仓库之后，清除之前旧仓库的物料可用库存
            this.data.forEach(item => {
              item.availableNum = (this.availableStock || []).find(val => val?.materialId == item.relatedId)?.availableNum || 0
            })
          }
        }).catch(error => {
          console.error(error);
        })
    },
    /** 
     * @description 获取仓位列表
    */
    getDefaultWarehousePosition(warehouseId) {
      WareHouseApi.getWarehousePositionSearch({ warehouseId, enabled: true })
        .then((result) => {
          if (result?.success) {
            let data = result?.data || []
            let warehousePositionList = []
            data.forEach(item => {
              let index = this.warehousePositionData.findIndex(position => position.value === item.id)
              if(index < 0) {
                warehousePositionList.push({
                  label: item.name,
                  value: item.id
                }) 
              }
            })
            this.warehousePositionData = this.warehousePositionData.concat(warehousePositionList) 
          }
        }).catch(error => {
          console.error(error);
        })
    },
    handleSubmit(params) {
      this.data = params.map(item => {
        return {
          ...item,
          relatedId: item.id
        }
      });
      this.getDefaultWarehouse();
    }
  },
  components: {
    [MaterialTable.name]: MaterialTable,
    [MaterialReceivingInformationDialog.name]: MaterialReceivingInformationDialog,
    [MaterialServiceBomDialog.name]: MaterialServiceBomDialog
  }
}
</script>

<style lang="scss" scoped>
.material-apply-dialog-container {
  ::v-deep .base-modal-body {
    padding: 24px;
  }

  .material-apply-method-panel {
    padding-bottom: 16px;
    .label-right {
      margin-right: 40px;
    }
    .tags-select {
      width: 320px;
    }
    .el-radio {
      color: $text-color-regular;
      margin-right: 24px;
    }
  }

  .btn-group {
    margin-top: 8px;
  }

  .warehouse-form {
    display: flex;
    justify-content: space-between;
    .warehouse-form-select {
      margin-right: 40px !important;
    }
  }

  .apply-remark-panel {
    padding: 32px 16px;
  }

  ::v-deep .form-item label {
    width: 80px !important;
  }
}
</style>